package cn.security.auth.util;

import lombok.extern.slf4j.Slf4j;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.keys.HmacKey;

import java.io.UnsupportedEncodingException;
import java.security.Key;

@Slf4j
public class JwtUtil {

    public static final String TOKEN_PREFIX = "account:token:";

    public static final int TOKEN_TIMEOUT = 1; // 1分钟Token过期


    public static final String JWT_PRIVATE_KEY = "misnice";

    /**
     * 生成token
     *
     * @param userId
     * @param expire
     * @return
     * @throws Exception
     */
    public static String generateToken(String userId, int expire) throws Exception {
        JwtClaims claims = new JwtClaims();
        claims.setSubject(userId);
        claims.setClaim("userId", userId);
        // token时长(分钟)
        claims.setExpirationTimeMinutesInTheFuture(expire == 0 ? 60 * 24 : expire);
        Key key = new HmacKey(JWT_PRIVATE_KEY.getBytes("UTF-8"));
        JsonWebSignature jws = new JsonWebSignature();
        jws.setPayload(claims.toJson());
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
        jws.setKey(key);
        jws.setDoKeyValidation(false); // relaxes the key length requirement
        //签名
        String token = jws.getCompactSerialization();
        return token;
    }

    /**
     * 解析token
     *
     * @param token
     * @return
     * @throws Exception
     */
    public static String getUserIdByToken(String token) throws Exception {
        if (token == null) {
            return null;
        }

        Key key = null;
        try {
            key = new HmacKey(JWT_PRIVATE_KEY.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        JwtConsumer jwtConsumer = new JwtConsumerBuilder()
                .setRequireExpirationTime()
                .setAllowedClockSkewInSeconds(30)
                .setRequireSubject()
                .setVerificationKey(key)
                .setRelaxVerificationKeyValidation() // relaxes key length requirement
                .build();

        JwtClaims processedClaims = null;
        processedClaims = jwtConsumer.processToClaims(token);
        return processedClaims.getClaimValue("userId").toString();
    }

}
